
package Ventanas;

import Mapas.LienzoParaArrastrarFiguras;
import Mapas.Rectangulo;
import Offline.Deshacer;
import Offline.Usuario;
import Online.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.*;

/**
 * @author Alvaro Garcia Tapia
 * @author Pablo Mosquera Diaz
 * @author Victor Navarro Ortego
 * @author Adrian Neila Serrano
 * @author Daniel Sanchez Suarez
 * 
 * @proyecto Gestor de Tareas Online
 * @version 1.61
 */
public class VentanaMapa extends JFrameConFondo implements ActionListener{ 

    private int x;
    private int y;
    private String name;
    private int numLista;
    private int tareaini;
    private ArrayList<Deshacer> deshacer = new ArrayList<Deshacer>();
    private JButton botonLogout;
    private JButton botonPreferencias;
    private JButton botonOnLine;
    private JButton botonMensajes;
    private JButton botonMapas;
    private JButton botonNuevo;
    private JButton botonEliminar;
    private JLabel labelInfo; 
    private Ventana ventana;
    private boolean online;
    private boolean repintando;
    private Comprobar comprobar;
    private String[][] mapas;
    private String []listas;
    private JTabbedPane panelConFichas;
    private Mapas mapa;
    private PopupMenu pm;
    
    
    public VentanaMapa(boolean online,String name,int numLista,int tareaini,ArrayList<Deshacer>deshacer,Ventana ventana){
        //constructor JFrame
	super("Gestor de Tareas Online"); 
        
        this.online = online;
        this.name = name;
        this.numLista = numLista;
        this.tareaini = tareaini;
        this.deshacer = deshacer;
        this.ventana = ventana;
        panelConFichas = new JTabbedPane();
    
                //Opciones de ventana
	this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        //se añade la opción de preguntar antes de salir
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                close();
            }
        });
        setLayout(null);
        //setSize(500,500);
	setExtendedState(MAXIMIZED_BOTH);
	Container contenidoPanel = getContentPane();
        contenidoPanel.setBackground(Color.LIGHT_GRAY);
        setImagen("objetos/fondo.jpg");
        setIconImage(new ImageIcon(getClass().getResource("objetos/icono.png")).getImage()); 
        
        
        comprobar = new Comprobar(name,null,numLista,tareaini,this);
        
                //Dimensiones de la pantalla
        Dimension dim=super.getToolkit().getScreenSize(); 
        x = (int)dim.width;
        y = (int)dim.height;
        
        labelInfo = new JLabel("Conectado como: "+name);
        labelInfo.setBounds((int)(x*0.01),(int)(y*0.01),300,10);
        labelInfo.setForeground(Color.white);
        add(labelInfo);
        
        botonMapas = new JButton("Mapas"); 
	botonMapas.setBounds((int)(x*0.005),(int)(y*0.04),40,40);
        botonMapas.setFont(new java.awt.Font("Arial", 0, 20)); 
        botonMapas.setActionCommand("Mapas");
        botonMapas.addActionListener(this);
        botonMapas.setToolTipText("Visión de Lista");
        botonMapas.setIcon(new ImageIcon(getClass().getResource("objetos/mapas.jpg")));
        add(botonMapas);

        
        //Constucción del boton Logout
	botonLogout = new JButton("Logout"); 
	add(botonLogout);
	botonLogout.setBounds((int)(x*0.89),(int)(y*0.02),100,30);
        botonLogout.setFont(new java.awt.Font("Arial", 0, 20)); 
        botonLogout.setActionCommand("Logout");
        botonLogout.addActionListener(this);
        botonLogout.setIcon(new ImageIcon(getClass().getResource("objetos/Logout.jpg")));
        
        //Constucción del boton preferencias
	botonPreferencias = new JButton("Preferencias"); 
	add(botonPreferencias);
	botonPreferencias.setBounds((int)(x*0.845),(int)(y*0.02),30,30);
        botonPreferencias.setFont(new java.awt.Font("Arial", 0, 20)); 
        botonPreferencias.setActionCommand("Preferencias");
        botonPreferencias.addActionListener(this);
        botonPreferencias.setToolTipText("Preferencias");
        botonPreferencias.setIcon(new ImageIcon(getClass().getResource("objetos/Preferencias.jpg")));  
        
        
                //Constucción del boton mensajes
	botonMensajes = new JButton("Mensajes"); 
	add(botonMensajes);
	botonMensajes.setBounds((int)(x*0.7),(int)(y*0.02),30,30);
        botonMensajes.setFont(new java.awt.Font("Arial", 0, 20)); 
        botonMensajes.setActionCommand("Mensajes");
        botonMensajes.addActionListener(this);
        botonMensajes.setToolTipText("Tareas Recibidas");
        if (comprobar.nuevos() && online)
            botonMensajes.setIcon(new ImageIcon(getClass().getResource("objetos/Mensaje Nuevo.jpg")));
            
        else{
            botonMensajes.setIcon(new ImageIcon(getClass().getResource("objetos/Mensaje.jpg")));
        }
        
        if (online){
            //Constucción del boton Logout
            botonOnLine = new JButton("Online");
            botonOnLine.setIcon(new ImageIcon(getClass().getResource("objetos/Online.jpg")));
            botonOnLine.setActionCommand("Online");
            comprobar.start();
        }
        else{
            botonOnLine = new JButton("Offline"); 
            botonOnLine.setIcon(new ImageIcon(getClass().getResource("objetos/Offline.jpg")));
            botonOnLine.setActionCommand("Offline");
        }
        
        add(botonOnLine);
        botonOnLine.setBounds((int)(x*0.745),(int)(y*0.02),100,30);
        botonOnLine.setFont(new java.awt.Font("Arial", 0, 20)); 
        botonOnLine.addActionListener(this);
        

         //Constucción del boton Nuevo
	botonNuevo = new JButton("Nuevo"); 
	add(botonNuevo);
	botonNuevo.setBounds((int)(x*0.8),(int)(y*0.12),225,40);
        botonNuevo.setFont(new java.awt.Font("Arial", 0, 20)); 
        botonNuevo.setActionCommand("Nuevo");
        botonNuevo.addActionListener(this);
        botonNuevo.setIcon(new ImageIcon(getClass().getResource("objetos/Crear Mapa.jpg")));

         //Constucción del boton eliminar
	botonEliminar = new JButton("Eliminar"); 
	add(botonEliminar);
	botonEliminar.setBounds((int)(x*0.8),(int)(y*0.22),225,40);
        botonEliminar.setFont(new java.awt.Font("Arial", 0, 20)); 
        botonEliminar.setActionCommand("Eliminar");
        botonEliminar.addActionListener(this);
        botonEliminar.setIcon(new ImageIcon(getClass().getResource("objetos/Eliminar Mapa.jpg")));

        //Se sacan los datos de los mapas
        mapa = conectarMapa();
        mapas = mapa.getMapas(name);
        //Se pintan las listas de los mapas
        for(int i = 0;i<mapas[0].length && mapas[0][i]!=null;i++){
            JPanel panel = new JPanel();
            panel.setBounds((int)(x*0.06),(int)(y*0.1), (((int)(x*0.7)/175)*175), (int)(x*0.48));
            panel.setLayout(null);
            Mapa(i,panel);        
            panelConFichas.addTab( mapa.getMapas(name)[1][i], panel);
        }
        panelConFichas.setBounds((int)(x*0.06),(int)(y*0.1), (((int)(x*0.7)/175)*175), (int)(x*0.48));
        panelConFichas.setFont(new java.awt.Font("Arial", 0, 20));
        panelConFichas.setBackground(Color.lightGray);
        
        getContentPane().add( panelConFichas );
        
        setVisible(true);
    
    }
    
    
        /**
     * Metodo que actualiza la tabla de tareas
     */
    public VentanaMapa ActualizarTablas(int numLista,int tareaini,ArrayList<Deshacer>deshacer){
        comprobar.parar();
        Opciones opciones = new Opciones();
        String[] datoO = opciones.getOpcion(name);
        Listas lista = conectarLista();
        VentanaMapa window;
        //Se crea una nueva ventana
            window = new VentanaMapa(online,name, numLista, tareaini, deshacer, ventana);
            
        repintando = true;
        //Se cierra la actual ventana
        setVisible(false);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
        return window;
    }
    
    
    
      /**
    * Función que se encarga de cerrar el programa
    */
    private void close(){
        this.setCursor(Cursor.WAIT_CURSOR);
        String message = "¿Está seguro de que quiere salir?";
        String title = "Logout";
        //Se pregunta si se desea desconectar
        int reply = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
        this.setCursor(Cursor.DEFAULT_CURSOR);
        //Si acepta 
        if (reply == JOptionPane.YES_OPTION)
        {
            this.setCursor(Cursor.WAIT_CURSOR);
            //Se muestra el aviso de que se cierra
            new AvisoDesconexion();
            //Se cierra el programa
            System.exit(0);
            //Se cierra la ventana de login
            setVisible(false);
            setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
            this.setCursor(Cursor.DEFAULT_CURSOR);
        }
   }
    
    
    /**
     * Metodo que construye el mapa
     * @param map
     * @param panel 
     */
    private void Mapa(final int map,JPanel panel){
        

        listas = mapa.getListas(mapas[0][map]);
        //Creación del popup para mover listas
        final PopupMenu pm = new PopupMenu("Mapas");
        final LienzoParaArrastrarFiguras c = new LienzoParaArrastrarFiguras(175);
        
        pm.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                if (!mapas[1][map].equals(e.getActionCommand())){
                    Point p = MouseInfo.getPointerInfo().getLocation();
                    String lista = ((Rectangulo)c.dameFigura2(p.x-(int)(x*0.08),p.y-(int)(y*0.2))).getlista();
                    mapa.moverlista(mapas[0][map], mapa.getid(e.getActionCommand(), name), name+lista);
                    ActualizarTablas(numLista,tareaini,deshacer);
                }
            }
        });
        pm.setActionCommand("Mover");
        int tam = 0;
        for(int i = 0; i<mapas.length && mapas[i]!=null;i++){
            pm.add(mapas[1][i]);
            tam++;
        }
        String [] maps = new String[tam];
        for(int i = 0;i<tam;i++){
            maps[i] = mapas[1][i];
        }
        //Creación del marco del mapa
        int ancho = (((int)(x*0.7)/175)*175);
        c.setBounds(0,0, ancho, (int)(x*0.48));
        c.setBackground(Color.white);
        c.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger() && c.dameFigura(e)!=null) {
                    pm.show(e.getComponent(),
                            e.getX(),
                            e.getY());
                }	  
            }
        });
        c.add(pm);
        panel.add(c);
        //Se ajusta el mapa a las preferencias del usuario
        Opciones opciones = conectarOpciones();
        String [] op = opciones.getOpcion(name);
        int numMax = Integer.parseInt(op[1]);
        int xx = -175;
        int yy = 0;
        for(int i=0;i<listas.length && listas[i]!=null;i++){
            Tareas tarea = conectarTarea();
            String[] tareas = tarea.gettareas(name, listas[i]);
            xx = xx + 175;
            if(xx>ancho){
                xx = 0;
                yy = yy + numMax*17+21;
            }
            else if(yy>(int)(x*0.48)){
                xx = 0;
                yy = 0;
            }
            c.addFigura(new Rectangulo(xx, yy, 50, 174, listas[i],tareas,numMax));
        }
        
    }

    
    /**
     * Metodo para conectar las listas con la bbdd
     * @return La conexión con la bbdd
     */
    private Listas conectarLista(){
        Listas lista = new Listas();
        boolean salir = false;
        //Si no se ha conectado
        while (!lista.estado() && !salir){
            this.setCursor(Cursor.WAIT_CURSOR);
            String message = "Fallo al conectar con el servidor.\n¿Desea volver a intentar conectar?";
            String title = "Error de conexión";
            //Se ofrece la opcion de reconectar
            int reply = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
                this.setCursor(Cursor.DEFAULT_CURSOR);
            //Si rechazo reconectar
            if (reply == JOptionPane.NO_OPTION){     
                this.setCursor(Cursor.WAIT_CURSOR);
                salir=true;
                new VentanaInicio();
                //Se cierra la ventana de login
                setVisible(false);
                setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
                this.setCursor(Cursor.DEFAULT_CURSOR);
            }
            //Si se acepto reconectar
            else{
                this.setCursor(Cursor.WAIT_CURSOR);
                //Se reconecta
                lista = new Listas();
                this.setCursor(Cursor.DEFAULT_CURSOR);
            }    
        }
        return lista;
    }
    
    
        /**
     * Metodo para conectar las tareas con la bbdd
     * @return La conexión con la bbdd
     */
    private Tareas conectarTarea(){
        //Se crea el objeto para actuar contra la bbdd
        Tareas tarea = new Tareas();
        boolean salir = false;
        //Si no se ha conectado
        while (!tarea.estado() && !salir){
            this.setCursor(Cursor.WAIT_CURSOR);
            String message = "Fallo al conectar con el servidor.\n¿Desea volver a intentar conectar?";
            String title = "Error de conexión";
            //Se ofrece la opcion de reconectar
            int reply = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
            this.setCursor(Cursor.DEFAULT_CURSOR);
            //Si rechazo reconectar
            if (reply == JOptionPane.NO_OPTION){     
                this.setCursor(Cursor.WAIT_CURSOR);
                salir=true;
                new VentanaInicio();
                //Se cierra la ventana de login
                setVisible(false);
                setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
                this.setCursor(Cursor.DEFAULT_CURSOR);
            }
            //Si se acepto reconectar
            else{
                this.setCursor(Cursor.WAIT_CURSOR);
                //Se reconecta
                tarea = new Tareas();
                this.setCursor(Cursor.DEFAULT_CURSOR);
            }    
        }
        return tarea;
    }
    
    
    
        /**
     * Metodo para conectar las tareas con la bbdd
     * @return La conexión con la bbdd
     */
    private Mapas conectarMapa(){
        //Se crea el objeto para actuar contra la bbdd
        Mapas mapa = new Mapas();
        boolean salir = false;
        //Si no se ha conectado
        while (!mapa.estado() && !salir){
            this.setCursor(Cursor.WAIT_CURSOR);
            String message = "Fallo al conectar con el servidor.\n¿Desea volver a intentar conectar?";
            String title = "Error de conexión";
            //Se ofrece la opcion de reconectar
            int reply = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
            this.setCursor(Cursor.DEFAULT_CURSOR);
            //Si rechazo reconectar
            if (reply == JOptionPane.NO_OPTION){     
                this.setCursor(Cursor.WAIT_CURSOR);
                salir=true;
                new VentanaInicio();
                //Se cierra la ventana de login
                setVisible(false);
                setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
                this.setCursor(Cursor.DEFAULT_CURSOR);
            }
            //Si se acepto reconectar
            else{
                this.setCursor(Cursor.WAIT_CURSOR);
                //Se reconecta
                mapa = new Mapas();
                this.setCursor(Cursor.DEFAULT_CURSOR);
            }    
        }
        return mapa;
    }
    
     /**
     * Metodo para conectar las opciones con la bbdd
     * @return La conexión con la bbdd
     */
    private Opciones conectarOpciones(){
        //Se crea el objeto para actuar contra la bbdd
        Opciones opciones = new Opciones();
        boolean salir = false;
        //Si no se ha conectado
        while (!opciones.estado() && !salir){
            this.setCursor(Cursor.WAIT_CURSOR);
            String message = "Fallo al conectar con el servidor.\n¿Desea volver a intentar conectar?";
            String title = "Error de conexión";
            //Se ofrece la opcion de reconectar
            int reply = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
            this.setCursor(Cursor.DEFAULT_CURSOR);
            //Si rechazo reconectar
            if (reply == JOptionPane.NO_OPTION){     
                this.setCursor(Cursor.WAIT_CURSOR);
                salir=true;
                new VentanaInicio();
                //Se cierra la ventana de login
                setVisible(false);
                setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
                this.setCursor(Cursor.DEFAULT_CURSOR);
            }
            //Si se acepto reconectar
            else{
                this.setCursor(Cursor.WAIT_CURSOR);
                //Se reconecta
                opciones = new Opciones();
                this.setCursor(Cursor.DEFAULT_CURSOR);
            }    
        }
        return opciones;
    }
    
    /**
     * Metodo que bloquea el hacer acciones en la ventana
     */
    public void activar(){
        repintando = false;
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        if(!repintando){
        String comando = e.getActionCommand();
        //Si se pulso el boton logout
            if (comando.equals("Logout")){
                this.setCursor(Cursor.WAIT_CURSOR);
                String message = "¿Está seguro de que quiere cerrar sesión?";
                String title = "Logout";
                //Se pregunta si se desea desconectar
                int reply = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
                this.setCursor(Cursor.DEFAULT_CURSOR);
                //Si acepta 
                if (reply == JOptionPane.YES_OPTION){
                    this.setCursor(Cursor.WAIT_CURSOR);    
                    new VentanaInicio();
                    setVisible(false);
                    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
                    this.setCursor(Cursor.DEFAULT_CURSOR);
                } 
            }
            else if(comando.equals("Mapas")){
                repintando = true;
                ventana.ActualizarTablas(numLista, tareaini, deshacer,online);
                setVisible(false);
                setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
            }
            else if(comando.equals("Preferencias")){
                repintando = true;
                comprobar.parar();
                new VentanaPreferencias(name,null,deshacer,this,online);
            } 
            
            else if(comando.equals("Online")){   
                    //Constucción del boton OnLine
                    remove(botonOnLine);
                    botonOnLine = new JButton("Offline"); 
                    add(botonOnLine);
                    botonOnLine.setBounds((int)(x*0.745),(int)(y*0.02),100,30);
                    botonOnLine.setFont(new java.awt.Font("Arial", 0, 20)); 
                    botonOnLine.setActionCommand("Offline");
                    botonOnLine.addActionListener(this);
                    botonOnLine.setIcon(new ImageIcon(getClass().getResource("objetos/Offline.jpg")));
                    repaint();
                
                    online = false;
            }
            else if(comando.equals("Offline")){   
                    //Constucción del boton OnLine
                    remove(botonOnLine);
                    botonOnLine = new JButton("Online"); 
                    add(botonOnLine);
                    botonOnLine.setBounds((int)(x*0.745),(int)(y*0.02),100,30);
                    botonOnLine.setFont(new java.awt.Font("Arial", 0, 20)); 
                    botonOnLine.setActionCommand("Online");
                    botonOnLine.addActionListener(this);
                    botonOnLine.setIcon(new ImageIcon(getClass().getResource("objetos/Online.jpg")));
                    repaint();
                    online = true;
                    ActualizarTablas(numLista,tareaini,deshacer);
                
                    
            } 
            else if(comando.equals("Mensajes")){
                if(!online)
                    JOptionPane.showMessageDialog (null,"No se pueden recibir tareas estando offline.",
                        	"Atención", JOptionPane.WARNING_MESSAGE);
                else{
                    repintando = true;
                    comprobar.parar();
                    new VentanaMensajes(name,null,numLista,tareaini,deshacer,this,online);
                }
            }
            
            else if(comando.equals("Nuevo")){
                String nombre = JOptionPane.showInputDialog(this,
                    "Introduzca el nombre del nuevo mapa.",
                    "Envio", JOptionPane.QUESTION_MESSAGE);
                if(nombre!=null)
                if (nombre.equals(""))
                    //Se muestra un aviso con el problema
                    JOptionPane.showMessageDialog (null,"Es obligatorio poner un nombre al nuevo mapa.",
                        "Atención", JOptionPane.WARNING_MESSAGE); 
                else{
                    mapa = conectarMapa();
                    if(mapa.existe(nombre, name))
                    JOptionPane.showMessageDialog (null,"Ya existe un mapa con ese nombre.",
                        "Atención", JOptionPane.ERROR_MESSAGE); 
                    else{
                        mapa.addMapa(nombre, name);
                        ActualizarTablas(numLista,tareaini,deshacer);
                    }
                }
            }
            else if(comando.equals("Eliminar")){
                int select = panelConFichas.getSelectedIndex();
                if(select != 0){
                    String message = "¿Está seguro de que quiere Eliminar el mapa "+mapas[1][select]+"?";
                    String title = "Eliminar";
                    //Se pide confirmacion para eliminar la tarea
                    int reply = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
                    //Si se confirma
                    if (reply == JOptionPane.YES_OPTION){
                        mapa = conectarMapa();
                        String nombre = mapas[1][select];
                        String []listas = mapa.getListas(mapa.getid(nombre, name));
                        for (int i = 0; i < listas.length && listas[i]!=null;i++)
                            mapa.moverlista(mapa.getid(nombre, name), mapa.getid("Principal", name), name+listas[i]);
                        mapa.eliminarMapa(nombre, name);
                        ActualizarTablas(numLista,tareaini,deshacer);
                    }
                }
                else
                    JOptionPane.showMessageDialog (null,"No se puede borrar un mapa predefinido.",
                        	"Atención", JOptionPane.ERROR_MESSAGE);
            }
        }
    }
    
    
}
